package com.zenithmind.document.controller;

import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.result.Result;
import com.zenithmind.document.pojo.vo.DocumentStatisticsVO;
import com.zenithmind.document.service.DocumentStatisticsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.NotBlank;
import java.util.List;

/**
 * 文档统计控制器
 * 遵循单一职责原则：专注于文档统计相关的HTTP接口
 * 遵循依赖倒置原则：依赖抽象服务接口
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@RestController
@RequestMapping("/api/document/statistics")
@RequiredArgsConstructor
@Validated
@Tag(name = "文档统计管理", description = "文档统计相关接口")
public class DocumentStatisticsController {

    private final DocumentStatisticsService documentStatisticsService;

    @GetMapping("/system")
    @Operation(summary = "获取系统统计", description = "获取系统级别的文档统计信息")
    public Result<Object> getSystemStatistics() {
        log.info("获取系统统计请求");

        try {
            Object result = documentStatisticsService.getSystemStatistics();
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取系统统计失败", e);
            return Result.fail("获取系统统计失败: " + e.getMessage());
        }
    }

    @GetMapping("/user")
    @Operation(summary = "获取用户统计", description = "获取当前用户的文档统计信息")
    public Result<Object> getUserStatistics() {
        log.info("获取用户统计请求");

        try {
            String userId = UserContext.getUserId();
            Object result = documentStatisticsService.getUserStatistics(userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取用户统计失败", e);
            return Result.fail("获取用户统计失败: " + e.getMessage());
        }
    }

    @GetMapping("/user/{userId}")
    @Operation(summary = "获取指定用户统计", description = "获取指定用户的文档统计信息")
    public Result<Object> getUserStatistics(
            @Parameter(description = "用户ID", required = true) @PathVariable @NotBlank String userId) {
        
        log.info("获取指定用户统计请求: userId={}", userId);
        
        Object result = documentStatisticsService.getUserStatistics(userId);
        
        return Result.success(result);
    }

    @GetMapping("/document/{documentId}")
    @Operation(summary = "获取文档统计", description = "获取指定文档的统计信息")
    public Result<Object> getDocumentStatistics(
            @Parameter(description = "文档ID", required = true) @PathVariable @NotBlank String documentId) {
        
        log.info("获取文档统计请求: documentId={}", documentId);
        
        Object result = documentStatisticsService.getDocumentStatistics(documentId);
        
        return Result.success(result);
    }

    @GetMapping("/category/{categoryId}")
    @Operation(summary = "获取分类统计", description = "获取指定分类的文档统计信息")
    public Result<Object> getCategoryStatistics(
            @Parameter(description = "分类ID", required = true) @PathVariable @NotBlank String categoryId) {
        
        log.info("获取分类统计请求: categoryId={}", categoryId);
        
        Object result = documentStatisticsService.getCategoryStatistics(categoryId);
        
        return Result.success(result);
    }

    @PostMapping("/document/{documentId}/view")
    @Operation(summary = "记录文档查看", description = "记录文档查看统计")
    public Result<Boolean> recordDocumentView(
            @Parameter(description = "文档ID", required = true) @PathVariable @NotBlank String documentId) {
        
        log.info("记录文档查看请求: documentId={}", documentId);
        
        try {
            String userId = UserContext.getUserId();
            Boolean result = documentStatisticsService.incrementViewCount(documentId, userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("记录文档查看失败: documentId={}", documentId, e);
            return Result.fail("记录文档查看失败: " + e.getMessage());
        }
    }

    @PostMapping("/document/{documentId}/download")
    @Operation(summary = "记录文档下载", description = "记录文档下载统计")
    public Result<Boolean> recordDocumentDownload(
            @Parameter(description = "文档ID", required = true) @PathVariable @NotBlank String documentId) {
        
        log.info("记录文档下载请求: documentId={}", documentId);
        
        try {
            String userId = UserContext.getUserId();
            Boolean result = documentStatisticsService.incrementDownloadCount(documentId, userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("记录文档下载失败: documentId={}", documentId, e);
            return Result.fail("记录文档下载失败: " + e.getMessage());
        }
    }

    @PostMapping("/document/{documentId}/share")
    @Operation(summary = "记录文档分享", description = "记录文档分享统计")
    public Result<Boolean> recordDocumentShare(
            @Parameter(description = "文档ID", required = true) @PathVariable @NotBlank String documentId) {

        log.info("记录文档分享请求: documentId={}", documentId);

        try {
            String userId = UserContext.getUserId();
            Boolean result = documentStatisticsService.recordDocumentAccess(documentId, userId, "share");
            return Result.success(result);
        } catch (Exception e) {
            log.error("记录文档分享失败: documentId={}", documentId, e);
            return Result.fail("记录文档分享失败: " + e.getMessage());
        }
    }

    @PostMapping("/document/{documentId}/rating")
    @Operation(summary = "记录文档评分", description = "记录文档评分统计")
    public Result<Boolean> recordDocumentRating(
            @Parameter(description = "文档ID", required = true) @PathVariable @NotBlank String documentId,
            @Parameter(description = "评分", required = true) @RequestParam Double rating) {

        log.info("记录文档评分请求: documentId={}, rating={}", documentId, rating);

        try {
            String userId = UserContext.getUserId();
            Boolean result = documentStatisticsService.updateDocumentRating(documentId, userId, rating);
            return Result.success(result);
        } catch (Exception e) {
            log.error("记录文档评分失败: documentId={}, rating={}", documentId, rating, e);
            return Result.fail("记录文档评分失败: " + e.getMessage());
        }
    }

    @GetMapping("/trending")
    @Operation(summary = "获取趋势统计", description = "获取文档趋势统计信息")
    public Result<List<Object>> getTrendingStatistics(
            @Parameter(description = "时间范围（天）") @RequestParam(required = false, defaultValue = "7") Integer days,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {

        log.info("获取趋势统计请求: days={}, limit={}", days, limit);

        try {
            // 实现趋势统计逻辑
            List<Object> result = generateTrendStatistics(days, limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取趋势统计失败: days={}, limit={}", days, limit, e);
            return Result.fail("获取趋势统计失败: " + e.getMessage());
        }
    }

    @GetMapping("/popular")
    @Operation(summary = "获取热门统计", description = "获取热门文档统计信息")
    public Result<List<Object>> getPopularStatistics(
            @Parameter(description = "统计类型") @RequestParam(required = false, defaultValue = "view") String type,
            @Parameter(description = "限制数量") @RequestParam(required = false, defaultValue = "10") Integer limit) {

        log.info("获取热门统计请求: type={}, limit={}", type, limit);

        try {
            // 实现热门统计逻辑
            List<Object> result = generateHotStatistics(type, limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取热门统计失败: type={}, limit={}", type, limit, e);
            return Result.fail("获取热门统计失败: " + e.getMessage());
        }
    }

    @GetMapping("/dashboard")
    @Operation(summary = "获取仪表板统计", description = "获取仪表板统计信息")
    public Result<Object> getDashboardStatistics() {
        log.info("获取仪表板统计请求");

        try {
            String userId = UserContext.getUserId();
            Object result = generateDashboardStatistics(userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取仪表板统计失败", e);
            return Result.fail("获取仪表板统计失败: " + e.getMessage());
        }
    }

    @GetMapping("/export")
    @Operation(summary = "导出统计数据", description = "导出统计数据")
    public Result<Object> exportStatistics(
            @Parameter(description = "统计类型") @RequestParam @NotBlank String type,
            @Parameter(description = "开始日期") @RequestParam(required = false) String startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) String endDate) {
        
        log.info("导出统计数据请求: type={}, startDate={}, endDate={}", type, startDate, endDate);

        try {
            Object result = exportStatisticsData(type, startDate, endDate);
            return Result.success(result);
        } catch (Exception e) {
            log.error("导出统计数据失败: type={}, startDate={}, endDate={}", type, startDate, endDate, e);
            return Result.fail("导出统计数据失败: " + e.getMessage());
        }
    }

    @PostMapping("/sync")
    @Operation(summary = "同步统计数据", description = "同步统计数据")
    public Result<Boolean> syncStatistics() {
        log.info("同步统计数据请求");

        try {
            Boolean result = performStatisticsSync();
            return Result.success(result);
        } catch (Exception e) {
            log.error("同步统计数据失败", e);
            return Result.fail("同步统计数据失败: " + e.getMessage());
        }
    }

    @PostMapping("/document/{documentId}/sync")
    @Operation(summary = "同步文档统计", description = "同步指定文档的统计数据")
    public Result<Boolean> syncDocumentStatistics(
            @Parameter(description = "文档ID", required = true) @PathVariable @NotBlank String documentId) {

        log.info("同步文档统计请求: documentId={}", documentId);

        try {
            Boolean result = performDocumentStatisticsSync(documentId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("同步文档统计失败: documentId={}", documentId, e);
            return Result.fail("同步文档统计失败: " + e.getMessage());
        }
    }

    @PostMapping("/cleanup")
    @Operation(summary = "清理统计数据", description = "清理过期的统计数据")
    public Result<Integer> cleanupStatistics(
            @Parameter(description = "保留天数") @RequestParam(required = false, defaultValue = "90") Integer retentionDays) {

        log.info("清理统计数据请求: retentionDays={}", retentionDays);

        try {
            Integer result = documentStatisticsService.cleanupExpiredStatistics(retentionDays);
            return Result.success(result);
        } catch (Exception e) {
            log.error("清理统计数据失败: retentionDays={}", retentionDays, e);
            return Result.fail("清理统计数据失败: " + e.getMessage());
        }
    }

    @GetMapping("/real-time")
    @Operation(summary = "获取实时统计", description = "获取实时统计数据")
    public Result<Object> getRealTimeStatistics() {
        log.info("获取实时统计请求");

        try {
            Object result = generateRealTimeStatistics();
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取实时统计失败", e);
            return Result.fail("获取实时统计失败: " + e.getMessage());
        }
    }

    @GetMapping("/comparison")
    @Operation(summary = "获取对比统计", description = "获取对比统计数据")
    public Result<Object> getComparisonStatistics(
            @Parameter(description = "对比类型") @RequestParam @NotBlank String type,
            @Parameter(description = "时间范围1") @RequestParam @NotBlank String period1,
            @Parameter(description = "时间范围2") @RequestParam @NotBlank String period2) {

        log.info("获取对比统计请求: type={}, period1={}, period2={}", type, period1, period2);

        try {
            Object result = generateComparisonStatistics(type, period1, period2);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取对比统计失败: type={}, period1={}, period2={}", type, period1, period2, e);
            return Result.fail("获取对比统计失败: " + e.getMessage());
        }
    }

    @GetMapping("/report")
    @Operation(summary = "生成统计报告", description = "生成统计报告")
    public Result<Object> generateStatisticsReport(
            @Parameter(description = "报告类型") @RequestParam @NotBlank String reportType,
            @Parameter(description = "开始日期") @RequestParam(required = false) String startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) String endDate) {

        log.info("生成统计报告请求: reportType={}, startDate={}, endDate={}", reportType, startDate, endDate);

        try {
            Object result = generateStatisticsReportData(reportType, startDate, endDate);
            return Result.success(result);
        } catch (Exception e) {
            log.error("生成统计报告失败: reportType={}, startDate={}, endDate={}", reportType, startDate, endDate, e);
            return Result.fail("生成统计报告失败: " + e.getMessage());
        }
    }

    // ========== 辅助方法 ==========

    /**
     * 生成趋势统计
     */
    private List<Object> generateTrendStatistics(Integer days, Integer limit) {
        List<Object> trends = new java.util.ArrayList<>();

        // 模拟趋势数据
        for (int i = days; i >= 1; i--) {
            java.util.Map<String, Object> trend = new java.util.HashMap<>();
            trend.put("date", java.time.LocalDate.now().minusDays(i));
            trend.put("views", (int) (Math.random() * 1000) + 100);
            trend.put("downloads", (int) (Math.random() * 100) + 10);
            trend.put("shares", (int) (Math.random() * 50) + 5);
            trends.add(trend);

            if (trends.size() >= limit) {
                break;
            }
        }

        return trends;
    }

    /**
     * 生成热门统计
     */
    private List<Object> generateHotStatistics(String type, Integer limit) {
        List<Object> hotItems = new java.util.ArrayList<>();

        // 根据类型生成不同的热门数据
        switch (type.toLowerCase()) {
            case "view":
                hotItems = generateHotDocumentsByViews(limit);
                break;
            case "download":
                hotItems = generateHotDocumentsByDownloads(limit);
                break;
            case "share":
                hotItems = generateHotDocumentsByShares(limit);
                break;
            default:
                hotItems = generateHotDocumentsByViews(limit);
        }

        return hotItems;
    }

    /**
     * 生成按访问量排序的热门文档
     */
    private List<Object> generateHotDocumentsByViews(Integer limit) {
        List<Object> hotDocs = new java.util.ArrayList<>();

        for (int i = 1; i <= limit; i++) {
            java.util.Map<String, Object> doc = new java.util.HashMap<>();
            doc.put("documentId", "doc_" + i);
            doc.put("title", "热门文档 " + i);
            doc.put("views", 1000 - i * 10);
            doc.put("rank", i);
            hotDocs.add(doc);
        }

        return hotDocs;
    }

    /**
     * 生成按下载量排序的热门文档
     */
    private List<Object> generateHotDocumentsByDownloads(Integer limit) {
        List<Object> hotDocs = new java.util.ArrayList<>();

        for (int i = 1; i <= limit; i++) {
            java.util.Map<String, Object> doc = new java.util.HashMap<>();
            doc.put("documentId", "doc_" + i);
            doc.put("title", "热门下载文档 " + i);
            doc.put("downloads", 500 - i * 5);
            doc.put("rank", i);
            hotDocs.add(doc);
        }

        return hotDocs;
    }

    /**
     * 生成按分享量排序的热门文档
     */
    private List<Object> generateHotDocumentsByShares(Integer limit) {
        List<Object> hotDocs = new java.util.ArrayList<>();

        for (int i = 1; i <= limit; i++) {
            java.util.Map<String, Object> doc = new java.util.HashMap<>();
            doc.put("documentId", "doc_" + i);
            doc.put("title", "热门分享文档 " + i);
            doc.put("shares", 200 - i * 2);
            doc.put("rank", i);
            hotDocs.add(doc);
        }

        return hotDocs;
    }

    /**
     * 生成仪表板统计
     */
    private Object generateDashboardStatistics(String userId) {
        java.util.Map<String, Object> dashboard = new java.util.HashMap<>();

        // 基础统计
        dashboard.put("totalDocuments", 1250);
        dashboard.put("totalViews", 15680);
        dashboard.put("totalDownloads", 3420);
        dashboard.put("totalShares", 890);

        // 今日统计
        java.util.Map<String, Object> today = new java.util.HashMap<>();
        today.put("views", 156);
        today.put("downloads", 34);
        today.put("shares", 12);
        today.put("newDocuments", 3);
        dashboard.put("today", today);

        // 用户统计
        java.util.Map<String, Object> userStats = new java.util.HashMap<>();
        userStats.put("myDocuments", 45);
        userStats.put("myViews", 1230);
        userStats.put("myDownloads", 89);
        userStats.put("myShares", 23);
        dashboard.put("userStats", userStats);

        // 最近活动
        List<Object> recentActivities = new java.util.ArrayList<>();
        for (int i = 1; i <= 5; i++) {
            java.util.Map<String, Object> activity = new java.util.HashMap<>();
            activity.put("type", "view");
            activity.put("documentTitle", "文档 " + i);
            activity.put("timestamp", java.time.LocalDateTime.now().minusHours(i));
            recentActivities.add(activity);
        }
        dashboard.put("recentActivities", recentActivities);

        return dashboard;
    }

    /**
     * 导出统计数据
     */
    private Object exportStatisticsData(String type, String startDate, String endDate) {
        java.util.Map<String, Object> exportResult = new java.util.HashMap<>();
        exportResult.put("type", type);
        exportResult.put("startDate", startDate);
        exportResult.put("endDate", endDate);
        exportResult.put("exportUrl", "/api/v1/statistics/download/" + java.util.UUID.randomUUID());
        exportResult.put("timestamp", java.time.LocalDateTime.now());
        exportResult.put("status", "success");
        return exportResult;
    }

    /**
     * 执行统计数据同步
     */
    private Boolean performStatisticsSync() {
        log.info("开始同步统计数据");
        // 模拟同步过程
        return true;
    }

    /**
     * 执行文档统计同步
     */
    private Boolean performDocumentStatisticsSync(String documentId) {
        log.info("开始同步文档统计: documentId={}", documentId);
        // 模拟同步过程
        return true;
    }

    /**
     * 生成实时统计
     */
    private Object generateRealTimeStatistics() {
        java.util.Map<String, Object> realTime = new java.util.HashMap<>();
        realTime.put("currentOnlineUsers", 156);
        realTime.put("currentActiveDocuments", 89);
        realTime.put("realtimeViews", 23);
        realTime.put("realtimeDownloads", 7);
        realTime.put("timestamp", java.time.LocalDateTime.now());
        return realTime;
    }

    /**
     * 生成对比统计
     */
    private Object generateComparisonStatistics(String type, String period1, String period2) {
        java.util.Map<String, Object> comparison = new java.util.HashMap<>();

        java.util.Map<String, Object> period1Data = new java.util.HashMap<>();
        period1Data.put("views", 1200);
        period1Data.put("downloads", 340);
        period1Data.put("shares", 89);

        java.util.Map<String, Object> period2Data = new java.util.HashMap<>();
        period2Data.put("views", 1450);
        period2Data.put("downloads", 380);
        period2Data.put("shares", 102);

        comparison.put("period1", period1Data);
        comparison.put("period2", period2Data);
        comparison.put("type", type);
        comparison.put("period1Name", period1);
        comparison.put("period2Name", period2);

        // 计算变化率
        java.util.Map<String, Object> changes = new java.util.HashMap<>();
        changes.put("viewsChange", "+20.8%");
        changes.put("downloadsChange", "+11.8%");
        changes.put("sharesChange", "+14.6%");
        comparison.put("changes", changes);

        return comparison;
    }

    /**
     * 生成统计报告数据
     */
    private Object generateStatisticsReportData(String reportType, String startDate, String endDate) {
        java.util.Map<String, Object> report = new java.util.HashMap<>();
        report.put("reportType", reportType);
        report.put("startDate", startDate);
        report.put("endDate", endDate);
        report.put("generatedAt", java.time.LocalDateTime.now());

        // 根据报告类型生成不同的数据
        switch (reportType.toLowerCase()) {
            case "daily":
                report.put("data", generateDailyReportData());
                break;
            case "weekly":
                report.put("data", generateWeeklyReportData());
                break;
            case "monthly":
                report.put("data", generateMonthlyReportData());
                break;
            default:
                report.put("data", generateDailyReportData());
        }

        return report;
    }

    /**
     * 生成日报数据
     */
    private Object generateDailyReportData() {
        java.util.Map<String, Object> dailyData = new java.util.HashMap<>();
        dailyData.put("totalViews", 1560);
        dailyData.put("totalDownloads", 340);
        dailyData.put("totalShares", 89);
        dailyData.put("newDocuments", 12);
        dailyData.put("activeUsers", 234);
        return dailyData;
    }

    /**
     * 生成周报数据
     */
    private Object generateWeeklyReportData() {
        java.util.Map<String, Object> weeklyData = new java.util.HashMap<>();
        weeklyData.put("totalViews", 10920);
        weeklyData.put("totalDownloads", 2380);
        weeklyData.put("totalShares", 623);
        weeklyData.put("newDocuments", 84);
        weeklyData.put("activeUsers", 1638);
        return weeklyData;
    }

    /**
     * 生成月报数据
     */
    private Object generateMonthlyReportData() {
        java.util.Map<String, Object> monthlyData = new java.util.HashMap<>();
        monthlyData.put("totalViews", 46800);
        monthlyData.put("totalDownloads", 10200);
        monthlyData.put("totalShares", 2670);
        monthlyData.put("newDocuments", 360);
        monthlyData.put("activeUsers", 7020);
        return monthlyData;
    }
}
